package com.forage.exp.handle;

import com.forage.exp.constant.GlobalErrorEnum;
import com.forage.exp.constant.ResponseStatusEnum;
import com.forage.exp.po.GlobalException;
import com.forage.exp.po.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.iceclean.logtrace.annotation.EnableLogTrace;
import top.iceclean.logtrace.bean.LogTrace;

/**
 * @author : George
 * @date : 2022-05-3
 *
 * SpringSecurity中的某些异常不会被自定义的处理器捕捉，需要额外处理
 */
@Slf4j
@RestControllerAdvice
//@EnableLogTrace
public class GlobalExceptionHandler {

    private LogTrace logTrace;

    /**
     * 捕获所有用户自定义异常
     * @param exception 用户自定义异常
     * @return 异常及请求信息
     */
    @ExceptionHandler(value = GlobalException.class)
    public Response handleGlobalException(GlobalException exception){
        log.error("全局异常处理器启动:捕获自定义异常");
        log.error(exception.toString());

        return new Response().setStatus(ResponseStatusEnum.INTERNAL_SERVER_ERROR)
                .addData("eCode",exception.getCode())
                .addData("eMsg",exception.getMessage());
    }

    /**
     * 捕获其他类型的异常
     * @param exception 其他类型的异常
     * @return 异常及请求信息
     */
    @ExceptionHandler(value = Exception.class)
    public Response handleException(Exception exception) {
        log.error("全局异常处理器启动:捕获其他异常");
        log.error(exception.toString());
//        exception.printStackTrace();

        if (exception instanceof AuthenticationException) {
            //SpringSecurity的剩余认证异常需要额外捕获
            return new Response().setStatus(ResponseStatusEnum.INTERNAL_SERVER_ERROR)
                    .addData("eCode",GlobalErrorEnum.AUTHENTICATION_EXCEPTION.getCode())
                    .addData("eMsg",GlobalErrorEnum.AUTHENTICATION_EXCEPTION.getMessage() + exception.getMessage());
        } else if (exception instanceof AccessDeniedException) {
            //SpringSecurity的剩余权限异常需要额外捕获
            return new Response().setStatus(ResponseStatusEnum.INTERNAL_SERVER_ERROR)
                    .addData("eCode",GlobalErrorEnum.AUTHORITY_EXCEPTION.getCode())
                    .addData("eMsg",GlobalErrorEnum.AUTHORITY_EXCEPTION.getMessage() + exception.getMessage());
        }
        //系统未知异常（剩余异常）捕获
        return new Response().setStatus(ResponseStatusEnum.INTERNAL_SERVER_ERROR)
                .addData("eCode",GlobalErrorEnum.UNKNOWN_EXCEPTION.getCode())
                .addData("eMsg",GlobalErrorEnum.UNKNOWN_EXCEPTION.getMessage() + exception.getMessage());
    }
}
